package com.pethospital.service.impl;

import com.pethospital.dao.AppointmentDao;
import com.pethospital.dao.impl.AppointmentDaoImpl;
import com.pethospital.entity.Appointment;
import com.pethospital.entity.PageResult;
import com.pethospital.service.AppointmentService;

import java.sql.Date;
import java.sql.Time;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 预约服务实现类
 * Appointment Service Implementation
 * 
 * @author PetHospital System
 * @version 1.0
 */
public class AppointmentServiceImpl implements AppointmentService {
    
    private AppointmentDao appointmentDao = new AppointmentDaoImpl();
    
    @Override
    public Appointment getAppointmentById(Integer appointmentId) {
        if (appointmentId == null || appointmentId <= 0) {
            return null;
        }
        return appointmentDao.findById(appointmentId);
    }
    
    @Override
    public List<Appointment> getAppointmentsByOwnerId(Integer ownerId) {
        if (ownerId == null || ownerId <= 0) {
            return null;
        }
        return appointmentDao.findByOwnerId(ownerId);
    }
    
    @Override
    public List<Appointment> getAppointmentsByPetId(Integer petId) {
        if (petId == null || petId <= 0) {
            return null;
        }
        return appointmentDao.findByPetId(petId);
    }
    
    @Override
    public boolean addAppointment(Appointment appointment) {
        // 验证预约数据
        String validationResult = validateAppointment(appointment, false);
        if (validationResult != null) {
            return false;
        }
        
        // 检查时间冲突
        if (checkTimeConflict(appointment.getAppointmentDate(), appointment.getAppointmentTime(), null)) {
            return false;
        }
        
        // 设置默认值
        if (appointment.getStatus() == null || appointment.getStatus().trim().isEmpty()) {
            appointment.setStatus("pending");
        }
        
        return appointmentDao.insert(appointment) > 0;
    }
    
    @Override
    public boolean updateAppointment(Appointment appointment) {
        if (appointment == null || appointment.getAppointmentId() == null) {
            return false;
        }
        
        // 验证预约数据
        String validationResult = validateAppointment(appointment, true);
        if (validationResult != null) {
            return false;
        }
        
        // 检查时间冲突（排除自己）
        if (checkTimeConflict(appointment.getAppointmentDate(), appointment.getAppointmentTime(), 
                            appointment.getAppointmentId())) {
            return false;
        }
        
        return appointmentDao.update(appointment) > 0;
    }
    
    @Override
    public boolean deleteAppointment(Integer appointmentId) {
        if (appointmentId == null || appointmentId <= 0) {
            return false;
        }
        
        return appointmentDao.delete(appointmentId) > 0;
    }
    
    @Override
    public boolean batchDeleteAppointments(Integer[] appointmentIds) {
        if (appointmentIds == null || appointmentIds.length == 0) {
            return false;
        }
        
        return appointmentDao.batchDelete(appointmentIds) > 0;
    }
    
    @Override
    public List<Appointment> getAllAppointments() {
        return appointmentDao.findAll();
    }
    
    @Override
    public PageResult<Appointment> getAppointmentsByPage(int currentPage, int pageSize) {
        if (currentPage <= 0) currentPage = 1;
        if (pageSize <= 0) pageSize = 10;
        
        return appointmentDao.findByPage(currentPage, pageSize);
    }
    
    @Override
    public PageResult<Appointment> getAppointmentsByOwnerAndPage(Integer ownerId, int currentPage, int pageSize) {
        if (ownerId == null || ownerId <= 0) {
            return new PageResult<>();
        }
        if (currentPage <= 0) currentPage = 1;
        if (pageSize <= 0) pageSize = 10;
        
        return appointmentDao.findByOwnerIdAndPage(ownerId, currentPage, pageSize);
    }
    
    @Override
    public PageResult<Appointment> searchAppointments(String petName, String serviceType, String status, 
                                                    Date appointmentDate, Integer ownerId, int currentPage, int pageSize) {
        if (currentPage <= 0) currentPage = 1;
        if (pageSize <= 0) pageSize = 10;
        
        return appointmentDao.findByCondition(petName, serviceType, status, appointmentDate, ownerId, currentPage, pageSize);
    }
    
    @Override
    public long getTotalAppointmentCount() {
        return appointmentDao.countAll();
    }
    
    @Override
    public long getAppointmentCountByOwner(Integer ownerId) {
        if (ownerId == null || ownerId <= 0) {
            return 0;
        }
        return appointmentDao.countByOwnerId(ownerId);
    }
    
    @Override
    public long getAppointmentCountByStatus(String status) {
        if (status == null || status.trim().isEmpty()) {
            return 0;
        }
        return appointmentDao.countByStatus(status);
    }
    
    @Override
    public long getAppointmentCountByDate(Date appointmentDate) {
        if (appointmentDate == null) {
            return 0;
        }
        return appointmentDao.countByDate(appointmentDate);
    }

    @Override
    public long getTodayAppointmentCount() {
        return appointmentDao.countTodayAppointments();
    }

    @Override
    public long getTodayAppointmentCountByOwnerId(Integer ownerId) {
        if (ownerId == null || ownerId <= 0) {
            return 0;
        }
        return appointmentDao.countTodayAppointmentsByOwnerId(ownerId);
    }

    @Override
    public long getPendingAppointmentCount() {
        return appointmentDao.countByStatus("pending");
    }

    @Override
    public long getPendingAppointmentCountByOwnerId(Integer ownerId) {
        if (ownerId == null || ownerId <= 0) {
            return 0;
        }
        return appointmentDao.countPendingAppointmentsByOwnerId(ownerId);
    }
    
    @Override
    public boolean updateAppointmentStatus(Integer appointmentId, String status) {
        if (appointmentId == null || appointmentId <= 0 || status == null || status.trim().isEmpty()) {
            return false;
        }
        
        // 验证状态值
        if (!"pending".equals(status) && !"confirmed".equals(status) && 
            !"completed".equals(status) && !"cancelled".equals(status)) {
            return false;
        }
        
        return appointmentDao.updateStatus(appointmentId, status) > 0;
    }
    
    @Override
    public boolean assignDoctor(Integer appointmentId, String doctorName) {
        if (appointmentId == null || appointmentId <= 0 || doctorName == null || doctorName.trim().isEmpty()) {
            return false;
        }
        
        return appointmentDao.assignDoctor(appointmentId, doctorName) > 0;
    }
    
    @Override
    public List<Object[]> getStatusStatistics() {
        return appointmentDao.getStatusStatistics();
    }
    
    @Override
    public List<Object[]> getServiceTypeStatistics() {
        return appointmentDao.getServiceTypeStatistics();
    }
    
    @Override
    public List<Appointment> getTodayAppointments() {
        return appointmentDao.findTodayAppointments();
    }
    
    @Override
    public List<Appointment> getPendingAppointments() {
        return appointmentDao.findPendingAppointments();
    }
    
    @Override
    public List<Appointment> getUpcomingAppointments() {
        return appointmentDao.findUpcomingAppointments();
    }

    @Override
    public List<Appointment> getRecentAppointmentsByOwnerId(Integer ownerId, int limit) {
        if (ownerId == null || ownerId <= 0) {
            return new ArrayList<>();
        }
        if (limit <= 0) limit = 5;

        return appointmentDao.findRecentByOwnerId(ownerId, limit);
    }
    
    @Override
    public boolean checkTimeConflict(Date appointmentDate, Time appointmentTime, Integer excludeId) {
        if (appointmentDate == null || appointmentTime == null) {
            return false;
        }
        
        return appointmentDao.checkTimeConflict(appointmentDate, appointmentTime, excludeId);
    }
    
    @Override
    public String validateAppointment(Appointment appointment, boolean isUpdate) {
        if (appointment == null) {
            return "预约信息不能为空";
        }
        
        // 验证宠物ID
        if (!isUpdate && (appointment.getPetId() == null || appointment.getPetId() <= 0)) {
            return "宠物ID不能为空";
        }
        
        // 验证主人ID
        if (!isUpdate && (appointment.getOwnerId() == null || appointment.getOwnerId() <= 0)) {
            return "主人ID不能为空";
        }
        
        // 验证预约日期
        if (appointment.getAppointmentDate() == null) {
            return "预约日期不能为空";
        }
        
        // 检查预约日期不能是过去的日期
        LocalDate today = LocalDate.now();
        LocalDate appointmentLocalDate = appointment.getAppointmentDate().toLocalDate();
        if (appointmentLocalDate.isBefore(today)) {
            return "预约日期不能是过去的日期";
        }
        
        // 验证预约时间
        if (appointment.getAppointmentTime() == null) {
            return "预约时间不能为空";
        }
        
        // 验证服务类型
        if (appointment.getServiceType() == null || appointment.getServiceType().trim().isEmpty()) {
            return "服务类型不能为空";
        }
        if (appointment.getServiceType().length() > 50) {
            return "服务类型长度不能超过50个字符";
        }
        
        // 验证症状描述
        if (appointment.getSymptoms() != null && appointment.getSymptoms().length() > 500) {
            return "症状描述长度不能超过500个字符";
        }
        
        // 验证状态
        if (appointment.getStatus() != null && !appointment.getStatus().trim().isEmpty()) {
            if (!"pending".equals(appointment.getStatus()) && !"confirmed".equals(appointment.getStatus()) && 
                !"completed".equals(appointment.getStatus()) && !"cancelled".equals(appointment.getStatus())) {
                return "状态只能是pending、confirmed、completed或cancelled";
            }
        }
        
        // 验证医生姓名
        if (appointment.getDoctorName() != null && appointment.getDoctorName().length() > 50) {
            return "医生姓名长度不能超过50个字符";
        }
        
        // 验证备注
        if (appointment.getNotes() != null && appointment.getNotes().length() > 500) {
            return "备注长度不能超过500个字符";
        }
        
        return null; // 验证通过
    }
    
    @Override
    public boolean hasPermission(Integer appointmentId, Integer userId, boolean isAdmin) {
        if (appointmentId == null || appointmentId <= 0 || userId == null || userId <= 0) {
            return false;
        }
        
        // 管理员有所有权限
        if (isAdmin) {
            return true;
        }
        
        // 普通用户只能操作自己的预约
        Appointment appointment = appointmentDao.findById(appointmentId);
        return appointment != null && appointment.getOwnerId().equals(userId);
    }

    @Override
    public List<String> getAllServiceTypes() {
        return Arrays.asList(
            "体检", "疫苗接种", "驱虫", "绝育手术", "外科手术",
            "内科治疗", "皮肤病治疗", "眼科检查", "牙科护理",
            "美容护理", "寄养服务", "急诊治疗", "其他"
        );
    }

    @Override
    public List<String> getAllDoctors() {
        return Arrays.asList(
            "张医生", "李医生", "王医生", "刘医生", "陈医生",
            "杨医生", "赵医生", "孙医生", "周医生", "吴医生"
        );
    }

    @Override
    public List<String> getAvailableTimeSlots(Date appointmentDate) {
        if (appointmentDate == null) {
            return Arrays.asList();
        }

        // 定义所有可能的时间段
        List<String> allTimeSlots = Arrays.asList(
            "09:00", "09:30", "10:00", "10:30", "11:00", "11:30",
            "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00"
        );

        // 查询当天已预约的时间
        List<Appointment> dayAppointments = appointmentDao.findByCondition(null, null, null, appointmentDate, null, 1, 100).getData();
        List<String> bookedTimes = dayAppointments.stream()
            .map(appointment -> appointment.getAppointmentTime().toString().substring(0, 5))
            .collect(Collectors.toList());

        // 返回可用时间段
        return allTimeSlots.stream()
            .filter(time -> !bookedTimes.contains(time))
            .collect(Collectors.toList());
    }

    @Override
    public boolean confirmAppointment(Integer appointmentId) {
        return updateAppointmentStatus(appointmentId, "confirmed");
    }

    @Override
    public boolean cancelAppointment(Integer appointmentId, String reason) {
        if (appointmentId == null || appointmentId <= 0) {
            return false;
        }

        // 更新状态为取消
        boolean result = updateAppointmentStatus(appointmentId, "cancelled");

        // 如果有取消原因，可以记录到备注中
        if (result && reason != null && !reason.trim().isEmpty()) {
            Appointment appointment = appointmentDao.findById(appointmentId);
            if (appointment != null) {
                String notes = appointment.getNotes();
                notes = (notes != null ? notes + "\n" : "") + "取消原因：" + reason;
                appointment.setNotes(notes);
                appointmentDao.update(appointment);
            }
        }

        return result;
    }

    @Override
    public boolean completeAppointment(Integer appointmentId) {
        return updateAppointmentStatus(appointmentId, "completed");
    }

    @Override
    public int importAppointments(List<Appointment> appointments) {
        if (appointments == null || appointments.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        for (Appointment appointment : appointments) {
            if (addAppointment(appointment)) {
                successCount++;
            }
        }

        return successCount;
    }

    @Override
    public List<Appointment> exportAppointments(Integer ownerId) {
        if (ownerId != null) {
            return appointmentDao.findByOwnerId(ownerId);
        } else {
            return appointmentDao.findAll();
        }
    }
}
